<template>
  <el-card>
    <!-- 表单 -->
    <el-form inline>
      <el-form-item>
        <el-input v-model="searchKeyword" placeholder="用户名" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" :icon="Search" @click="getUserByUserName()">查询</el-button>
        <el-button @click="emptySearchKeyword()">清空</el-button>
      </el-form-item>
    </el-form>
    <!-- 功能按钮 -->
    <div class="addAndDelete">
      <el-button type="primary" @click="saveUserInfo()">添加</el-button>
      <el-button type="danger" :disabled="!ids.length" @click="deleteChecked()">批量删除</el-button>
    </div>
    <!-- 表格 -->
    <el-table :data="userList" v-loading="loading" stripe border @selection-change="checkboxChange" style="width: 100%">
      <el-table-column type="selection" align="center" width="50" />
      <el-table-column label="序号" align="center" type="index" width="60" />
      <el-table-column prop="username" label="用户名" />
      <el-table-column prop="nickName" label="用户昵称" />
      <el-table-column label="角色列表">
        <template v-slot="{row}">
          <el-tag v-for="(rn, index) in switchArray(row.roleName, ',')" :key="index" style="margin: 3px 6px 3px 0">{{rn}}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="gmtCreate" label="创建时间" />
      <el-table-column prop="gmtModified" label="更新时间" />
      <el-table-column label="操作" align="center">
        <template v-slot="{row}">
          <el-button type="info" :icon="UserFilled" size="small" @click="setUserRole(row)"></el-button>
          <el-button type="primary" :icon="Edit" size="small" @click="deleteUserInfo(row)"></el-button>
          <el-popconfirm :title="`你确定删除${row.username}`" @confirm="deleteUser(row.id)">
            <template #reference>
              <el-button type="danger" :icon="Delete" size="small"></el-button>
            </template>
          </el-popconfirm>
          
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页器 -->
    <el-pagination
      v-model:currentPage="pageNo"
      v-model:page-size="pageSize"
      :page-sizes="[5, 10, 20, 40]"
      layout="prev, pager, next, jumper, ->, sizes, total"
      :total="total"
      @size-change="getUserPageList(1, val)"
      @current-change="getUserPageList(val, pageSize)"
      style="margin-top: 20px"
    />
    <!-- 新增/修改用户对话框 -->
    <el-dialog v-model="dialogFormVisible" :title="userInfo.id? '修改用户': '添加用户'">
      <el-form :model="userInfo" ref="ruleFormRef" :rules="rules" style="width: 80%" label-width="100px">
        <el-form-item prop="username" label="用户名">
          <el-input v-model="userInfo.username" />
        </el-form-item>
        <el-form-item label="用户昵称">
          <el-input v-model="userInfo.nickName" />
        </el-form-item>
        <el-form-item prop="password" label="用户密码" v-if="!userInfo.id">
          <el-input v-model="userInfo.password" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取消</el-button>
          <el-button type="primary" @click="saveOrDeleteUser()"
            >确定</el-button
          >
        </span>
      </template>
    </el-dialog>
    <!-- 分配角色对话框 -->
    <el-dialog v-model="setRoleFormVisible" title="分配角色">
      <el-form style="width: 90%" label-width="100px">
        <el-form-item label="用户名">
          <el-input disabled v-model="assignUser.username" />
        </el-form-item>
        <el-form-item label="角色列表">
          <el-checkbox
            v-model="checkAll"
            :indeterminate="isIndeterminate"
            @change="handleCheckAllChange"
            >全选</el-checkbox
          >
          <el-checkbox-group
            v-model="checkedRoleIdList"
            @change="handleCheckedChange"
          >
            <el-checkbox v-for="role in allRoleList" :key="role.id" :label="role.id">{{
              role.roleName
            }}</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>  
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="setRoleFormVisible = false">取消</el-button>
          <el-button type="primary" @click="doAssign()"
            >确定</el-button
          >
        </span>
      </template>
    </el-dialog>
  </el-card>
</template>
<script lang="ts">
export default {
  name: 'User'
}
</script>
<script lang="ts" setup>

// 引入图标组件
import { Search, Delete, Edit, User, UserFilled } from '@element-plus/icons-vue'
// 引入消息提示组件
import {ElMessage, ElMessageBox} from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'

import {ref, reactive, onMounted} from 'vue'
// 引入管理用户相关的接口函数
import {getUserPageListApi, deleteUserByIdApi, saveOrDeleteUserApi, batchDeleteUsersApi, toAssignApi, doAssignApi} from '@/api/acl/user'
// 引入管理用户相关的接口类型
import {UserInfoModel, UserInfoListModel} from '@/api/acl/model/userModel'
// 引入角色相关的接口类型
import type {RoleListModel} from '@/api/acl/model/roleModel' 


const userList = ref<UserInfoListModel>([]) // 定义表格数据
const total = ref(0) // 定义数据总数
const pageNo = ref(1) // 定义当前页码
const pageSize = ref(5) // 定义每页展示的数据个数
const loading = ref<boolean>(false) // 定义载入效果标识
const dialogFormVisible = ref<boolean>(false) // 对话框是否显示标识
// 定义初始管理员对象
const initUserInfo = () => ({
  id: undefined,
  username: '',
  password: '',
  nickName: ''
})
const userInfo = ref<UserInfoModel>(initUserInfo())
const ids = ref<string[]>([]) // 定义选中状态的管理员Id数组

// 定义校验规则
const rules = reactive<FormRules>({
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 6, max: 12, message: '密码长度为6-12', trigger: 'blur' },
  ],
})  
const ruleFormRef = ref<FormInstance>() // 定义用来收集表单form对象

const setRoleFormVisible = ref<boolean>(false) // 分配角色对话框显示标识
const allRoleList = ref<RoleListModel>([]) // 定义存储管理员下所有的角色列表数据
const checkedRoleIdList = ref<string[]>([]) // 定义存储管理员下所有选择的角色列表数据
const checkAll = ref(false) // 是否全选
const isIndeterminate = ref(true) // 不确定状态
const assignUser = reactive<UserInfoModel>(initUserInfo()) // 被分配角色的对象

const searchKeyword = ref<string>('') // 定义输入框搜索值


// 定义获取管理用户分页列表数据
const getUserPageList = async (page: number = pageNo.value, limit: number = pageSize.value) => {
  // 更新页码及每页展示数量
  pageNo.value = page
  pageSize.value = limit
  loading.value = true
  const result = await getUserPageListApi(page, limit, {
    username: searchKeyword.value
  })
  // 更新数据
  total.value = result.total
  userList.value = result.items
  loading.value = false
}
// 定义根据id移除对应管理员对象的函数
const deleteUser = async (id: string) => {
  try {
    const result = await deleteUserByIdApi(id)
    // 更新列表
    getUserPageList()
    ElMessage.success('删除成功')
  } catch (error: any) {
    ElMessage.warning(error.message)
  }
}
// 新增管理员
const saveUserInfo = () => {
  // 重置
  userInfo.value = initUserInfo()
  // 显示对话框
  dialogFormVisible.value = true
  // 移除表单校验信息
  ruleFormRef.value && ruleFormRef.value.clearValidate()
}
// 修改管理员
const deleteUserInfo = (user: UserInfoModel) => {
  userInfo.value = {
    id: user.id,
    username: user.username,
    password: user.password,
    nickName: user.nickName
  }
  // 显示对话框
  dialogFormVisible.value = true
  // 移除表单校验信息
  ruleFormRef.value && ruleFormRef.value.clearValidate()
}
// 新增/修改管理员对象 确定按钮回调
const saveOrDeleteUser = () => {
  // 表单整体校验
    ruleFormRef.value?.validate(async (valid) => {
      // 校验失败
      if (!valid) return 
      // 校验成功
      try {
        const result = await saveOrDeleteUserApi(userInfo.value)
        dialogFormVisible.value = false
        // 操作成功 更新列表
        getUserPageList(1, pageSize.value)
        ElMessage.success('操作成功')
      } catch (error: any) {
        ElMessage.warning(error.message)
      }
    })
}
// 表格复选框值变化时
const checkboxChange = (selection: UserInfoListModel) => {
  ids.value = []
  selection.forEach(item => {
    ids.value.push(item.id as string)
  })
}
// 批量删除
const deleteChecked = () => {
  ElMessageBox.confirm(
    '此行为会永久删除数据，请问是否继续操作',
    '提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
    .then(async () => {
      const result = await batchDeleteUsersApi(ids.value)
      ElMessage({
        type: 'success',
        message: '删除成功',
      })
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '取消操作',
      })
    })
}
// 批量操作角色列表
const handleCheckAllChange = (val: boolean) => {
  checkedRoleIdList.value = val ? allRoleList.value.map(item => item.id) as string[] : []
  isIndeterminate.value = false
}
// 操作角色对象
const handleCheckedChange = (value: string[]) => {
  // 获取选中角色数量
  const checkedCount = value.length
  // 判断是否全选
  checkAll.value = checkedCount === allRoleList.value.length 
  // 判断是否为不确定状态 
  isIndeterminate.value = checkedCount > 0 && checkedCount < allRoleList.value.length
}
// 设置用户角色的回调
const setUserRole = async (row: UserInfoModel) => {
  allRoleList.value = []
  setRoleFormVisible.value = true
  assignUser.username = row.username
  assignUser.id = row.id
  try {
    // 调用接口获取数据
    const result = await toAssignApi(row.id as string)
    // 更新数据
    allRoleList.value = result.allRolesList
    // 获取被选择的角色Id
    checkedRoleIdList.value = result.assignRoles.map(item => item.id) as string[]
  } catch (error: any) {
    ElMessage.warning(error.message)
  }
}
// 为当前用户分配角色
const doAssign = async () => {
  try {
    await doAssignApi(assignUser.id as string, checkedRoleIdList.value.join())
    ElMessage.success('角色分配成功')
    // 重新渲染列表数据
    getUserPageList()
    setRoleFormVisible.value = false
  } catch (error: any) {
    ElMessage.warning(error.message)
  }
}
// 根据 关键字 获取对应管理员
const getUserByUserName = async () => {
  getUserPageList()  
}
// 清空输入框关键字回调
const emptySearchKeyword = async () => {
  searchKeyword.value = ''
  getUserPageList()
}

// 组件挂载完毕
onMounted(() => {
  getUserPageList()
})



// 将字符串转为数组
function switchArray (str: string, flag: string) {
  return str.split(flag).filter(item => item)
}
</script>
<style scoped>
.addAndDelete {
  margin: 20px 0;
}
:deep(.el-overlay-dialog) {
  top: 140px
}
</style>